IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
(sts & DMA_GSTS_SIRTPS), sts);
+ /* After set SIRTP, must globally invalidate the interrupt entry cache */
+ iommu_flush_iec_global(iommu);
+
/* enable comaptiblity format interrupt pass through */
gcmd |= DMA_GCMD_CFI;
dmar_writel(iommu->reg, DMAR_GCMD_REG, gcmd);
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
(sts & DMA_GSTS_IRES), sts);
- /* After set SIRTP, we should do globally invalidate the IEC */
- iommu_flush_iec_global(iommu);
-
return init_apic_pin_2_ir_idx();
}
for_each_drhd_unit ( drhd )
{
iommu = drhd->iommu;
- ret = iommu_set_root_entry(iommu);
- if ( ret )
- {
- gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: set root entry failed\n");
- return -EIO;
- }
-
if ( iommu->vector < 0 )
{
vector = iommu_set_interrupt(iommu);
}
}
+ for_each_drhd_unit ( drhd )
+ {
+ iommu = drhd->iommu;
+ ret = iommu_set_root_entry(iommu);
+ if ( ret )
+ {
+ gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: set root entry failed\n");
+ return -EIO;
+ }
+ }
+
+ /*
+ * After set root entry, must globally invalidate context cache, and
+ * then globally invalidate IOTLB
+ */
+ iommu_flush_all();
+
return 0;
}
{
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
- struct iommu_flush *flush;
u32 i;
if ( !iommu_enabled )
return;
- /* Re-initialize the register-based flush functions.
- * In iommu_flush_all(), we invoke iommu_flush_{context,iotlb}_global(),
- * but at this point, on hosts that support QI(Queued Invalidation), QI
- * hasn't been re-enabed yet, so for now let's use the register-based
- * invalidation method before invoking init_vtd_hw().
- */
- if ( iommu_qinval )
- {
- for_each_drhd_unit ( drhd )
- {
- iommu = drhd->iommu;
- flush = iommu_get_flush(iommu);
- flush->context = flush_context_reg;
- flush->iotlb = flush_iotlb_reg;
- }
- }
-
- /* Not sure whether the flush operation is required to meet iommu
- * specification. Note that BIOS also executes in S3 resume and iommu may
- * be touched again, so let us do the flush operation for safety.
- */
- iommu_flush_all();
-
if ( init_vtd_hw() != 0 && force_iommu )
panic("IOMMU setup failed, crash Xen for security purpose!\n");